package com.aaa.doctor.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.aaa.doctor.dto.SchedulingDto;
import com.aaa.doctor.feign.system.UserFeign;
import com.aaa.doctor.mapper.SchedulingMapper;
import com.aaa.doctor.service.SchedulingService;
import com.aaa.doctor.vo.Scheduling2Vo;
import com.aaa.doctor.vo.Scheduling3Vo;
import com.aaa.doctor.vo.SchedulingVo;
import com.aaa.entity.Scheduling;
import com.aaa.entity.User;
import com.aaa.utils.JwtUtil;
import com.aaa.utils.WebUtil;
import com.aaa.vo.Result;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author MuChengGuo
 * @date 2023/3/28 9:07
 * Description: TODO
 **/
@Service
public class SchedulingServiceImpl implements SchedulingService {
    @Autowired(required = false)
    private SchedulingMapper schedulingMapper;
    @Autowired
    private UserFeign userFeign;

    @Override
    public Result queryScheduling(SchedulingVo schedulingVo) {
        //查询所有的医生信息
        Map<String, Object> map = new HashMap<>();
        map.put("userId", schedulingVo.getUserId());
        map.put("deptId", schedulingVo.getDeptId());
        List<User> listAllUser = userFeign.getListAllUser(map);
        return querySchedulingByCondition(schedulingVo, listAllUser);
    }

    @Override
    public Result queryMyScheduling(SchedulingVo schedulingVo) {
        // 获取token
        HttpServletRequest request = WebUtil.getRequest();
        Map<String, Object> info = JwtUtil.getTokenChaim(request.getHeader("token"));
        String phone = (String) info.get("username");
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone);
        User byUsername = userFeign.getByUsername(phone);
        List<User> list = new ArrayList<>();
        list.add(byUsername);

        schedulingVo.setUserId(byUsername.getUserId());
        return querySchedulingByCondition(schedulingVo, list);
    }

    /**
     * 修改排班信息
     *
     * @param scheduling2Vo
     * @return
     */
    @Override
    public Result modification(Scheduling2Vo scheduling2Vo) {
        // 查询出账号登陆者的姓名
        HttpServletRequest request = WebUtil.getRequest();
        String phone = (String) JwtUtil.getTokenChaim(request.getHeader("token")).get("username");
        String userName = userFeign.getByUsername(phone).getUserName();

        // 获取传输的数据
        List<SchedulingDto> allDatas = scheduling2Vo.getAllDatas();
        String beginDate = scheduling2Vo.getBeginDate();

        int del = 1;
        int update = 1;
        DateTime dateTime = DateUtil.parse(scheduling2Vo.getBeginDate(), "yyyy-MM-dd");
        Map<String, String> map = initMap(dateTime);
        Set<String> keys = map.keySet();

        // 遍历
        for (SchedulingDto allData : allDatas) {
            // 删除
            QueryWrapper<Scheduling> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", allData.getUserId());
            wrapper.eq("subsection_type", allData.getSubsectionType());
            wrapper.between("scheduling_day", scheduling2Vo.getBeginDate(), scheduling2Vo.getEndDate());
            schedulingMapper.delete(wrapper);

            Collection<String> schedulingType = allData.getSchedulingType();//获取排班
            Iterator<String> scheduling = schedulingType.iterator();//排班 1门诊  2急诊
            Iterator<String> key = keys.iterator();//获取当前的日期
            for (int i = 0; i < keys.size(); i++) {
                String next = scheduling.next();
                String next1 = key.next();
                if (!next.equals("")) {
                    Scheduling user = new Scheduling();
                    user.setUserId(allData.getUserId());
                    user.setDeptId(allData.getDeptId());
                    user.setSubsectionType(allData.getSubsectionType());
                    //DateUtil.offsetDay(scheduling2Vo.getBeginDate(), i)
                    user.setSchedulingDay(next1);
                    user.setSchedulingType(next);
                    user.setCreateBy(userName);
                    user.setCreateTime(new Date());
                    schedulingMapper.insert(user);
                }
            }
        }
        return new Result(2000, "成功", null);
    }

    /**
     * 门诊挂号
     *
     * @param scheduling3Vo
     * @return
     */
    @Override
    public Result<List<Scheduling>> listDeptForScheduling(Scheduling3Vo scheduling3Vo) {
        QueryWrapper<Scheduling> wrapper = new QueryWrapper<>();
        if (Objects.nonNull(scheduling3Vo.getSchedulingDay())) {
            wrapper.eq("scheduling_day", scheduling3Vo.getSchedulingDay());
        }
        if (Objects.nonNull(scheduling3Vo.getDeptId())) {
            wrapper.eq("dept_id", scheduling3Vo.getDeptId());
        }
        if (Objects.nonNull(scheduling3Vo.getSchedulingType())) {
            wrapper.eq("scheduling_type", scheduling3Vo.getSchedulingType());
        }
        if (Objects.nonNull(scheduling3Vo.getSubsectionType())) {
            wrapper.eq("subsection_type", scheduling3Vo.getSubsectionType());
        }
        List<Scheduling> schedulings = schedulingMapper.selectList(wrapper);


        return new Result<>(2000, "成功", schedulings);
    }

    /**
     * 封装前端需要的时间
     *
     * @param schedulingVo
     * @param listAllUser
     * @return
     */
    private Result querySchedulingByCondition(SchedulingVo schedulingVo, List<User> listAllUser) {
        // 获取当前时间
        DateTime today = DateUtil.date();
        //判断前端是否传入当前时间
        if (StringUtils.hasText(schedulingVo.getQueryDate())) {
            //转换格式
            today = DateUtil.parse(schedulingVo.getQueryDate(), "yyyy-MM-dd");
            // 返回的如果是   2表示周一   1表示周日
            int i = DateUtil.dayOfWeek(today);
            if (i == 1) {
                // 下一周 周一的日期
                today = DateUtil.offsetDay(today, 1);
            } else {
                // 上一周 周日的日期
                today = DateUtil.offsetDay(today, -1);
            }
        }
        //开始时间与结束时间
        DateTime beginDate = DateUtil.beginOfWeek(today);
        DateTime endDate = DateUtil.endOfWeek(today);
        schedulingVo.setBeginDate(DateUtil.format(beginDate, "yyyy-MM-dd"));
        schedulingVo.setEndDate(DateUtil.format(endDate, "yyyy-MM-dd"));

        //根据条件查询排班表
        List<Scheduling> schedulings = queryByCondition(schedulingVo);
        List<SchedulingDto> schedulingDtos = new ArrayList<SchedulingDto>();

        //遍历医生
        for (User user : listAllUser) {
            SchedulingDto schedulingDto1 = new SchedulingDto(user.getUserId(), user.getDeptId(), "1", initMap(beginDate));
            SchedulingDto schedulingDto2 = new SchedulingDto(user.getUserId(), user.getDeptId(), "2", initMap(beginDate));
            SchedulingDto schedulingDto3 = new SchedulingDto(user.getUserId(), user.getDeptId(), "3", initMap(beginDate));
            //每个用户都有这三条数据
            schedulingDtos.add(schedulingDto1);
            schedulingDtos.add(schedulingDto2);
            schedulingDtos.add(schedulingDto3);
            for (Scheduling scheduling : schedulings) {
                // 排班的人员id
                Long userId = scheduling.getUserId();
                //排班的日期
                String schedulingDay = scheduling.getSchedulingDay();
                //排班的类型
                String subsectionType = scheduling.getSubsectionType();
                if (user.getUserId().equals(userId)) {
                    switch (subsectionType) {
                        case "1":
                            Map<String, String> record1 = schedulingDto1.getRecord();
                            record1.put(schedulingDay, scheduling.getSchedulingType());
                            break;
                        case "2":
                            Map<String, String> record2 = schedulingDto2.getRecord();
                            record2.put(schedulingDay, scheduling.getSchedulingType());
                            break;
                        case "3":
                            Map<String, String> record3 = schedulingDto3.getRecord();
                            record3.put(schedulingDay, scheduling.getSchedulingType());
                            break;
                    }
                }
            }
            schedulingDto1.setSchedulingType(schedulingDto1.getRecord().values());
            schedulingDto2.setSchedulingType(schedulingDto2.getRecord().values());
            schedulingDto3.setSchedulingType(schedulingDto3.getRecord().values());
        }

        //封装表数据
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("tableData", schedulingDtos);
        result.put("beginDate", DateUtil.format(beginDate, "yyyy-MM-dd"));
        result.put("endDate", DateUtil.format(endDate, "yyyy-MM-dd"));
        //封装表头
        Object labelName = initLabel(beginDate);
        result.put("labelName", labelName);

        return new Result(2000, "成功", result);
    }

    /**
     * 封装表头信息
     */
    private Object initLabel(DateTime beginTime) {
        String[] labelNames = new String[7];
        for (int i = 0; i < 7; i++) {
            DateTime dateTime = DateUtil.offsetDay(beginTime, i);
            labelNames[i] = DateUtil.format(dateTime, "yyyy-MM-dd") + FormatterWeek(i);
        }
        return labelNames;
    }

    /**
     * 翻译周
     *
     * @param i
     * @return
     */
    private String FormatterWeek(int i) {
        switch (i) {
            case 0:
                return "(周一)";
            case 1:
                return "(周二)";
            case 2:
                return "(周三)";
            case 3:
                return "(周四)";
            case 4:
                return "(周五)";
            case 5:
                return "(周六)";
            default:
                return "(周日)";
        }
    }

    /**
     * 初始化当前用户这周的排班信息
     *
     * @param beginDate
     * @return
     */
    private Map<String, String> initMap(DateTime beginDate) {
        TreeMap<String, String> map = new TreeMap<>();
        for (int i = 0; i < 7; i++) {
            DateTime dateTime = DateUtil.offsetDay(beginDate, i);
            String key = DateUtil.format(dateTime, "yyyy-MM-dd");
            map.put(key, "");
        }
        return map;
    }

    /**
     * 根据条件查询排班信息
     *
     * @param schedulingVo
     * @return
     */
    public List<Scheduling> queryByCondition(SchedulingVo schedulingVo) {
        QueryWrapper<Scheduling> wrapper = new QueryWrapper<>();
        if (schedulingVo.getUserId() != null) {
            wrapper.eq("user_id", schedulingVo.getUserId());
        }
        if (schedulingVo.getDeptId() != null) {
            wrapper.eq("dept_id", schedulingVo.getDeptId());
        }
        if (StringUtils.hasText(schedulingVo.getBeginDate())) {
            wrapper.ge("scheduling_day", schedulingVo.getBeginDate());
        }
        if (StringUtils.hasText(schedulingVo.getEndDate())) {
            wrapper.le("scheduling_day", schedulingVo.getEndDate());
        }
        return schedulingMapper.selectList(wrapper);
    }
}
